home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / disk-man / userflop.2 / userflop / userfloppy0.2 / userumount.c < prev   
Encoding:
C/C++ Source or Header  |  1994-06-30  |  4.0 KB  |  176 lines

  1. /* 
  2.     umount.c - by Peter Orbaek <poe@daimi.aau.dk> 
  3.  
  4.     Copyright (C) 1992,93 Peter Orbaek.
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21.  
  22. #define _POSIX_SOURCE 1
  23. #include <stdio.h>
  24. #include <mntent.h>
  25. #include <unistd.h>
  26. #include <fcntl.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. #include <getopt.h>
  30. #include <sys/mount.h>
  31. #include <sys/types.h>
  32.  
  33. #define MTAB_FILE MOUNTED
  34. #define LOCK_FILE "/etc/mtab~"
  35. #define UFSTAB    "/etc/ufstab"
  36.  
  37. int opt_all          = 0;
  38. int opt_verbose      = 0;
  39. int opt_usermount    = 0;
  40.  
  41. char mnttype[200] = "";
  42. char *mntdev;
  43.  
  44. void usage(), err(char *);
  45. void lock_mtab();
  46. int do_umount(struct mntent *);
  47.  
  48. void usage()
  49. {
  50.     fprintf(stderr,
  51.         "Usage: userumount [-v] dev|dir\n");
  52.     exit(1);
  53. }
  54.  
  55. int main(int argc, char *argv[])
  56. {
  57.     char c;
  58.     FILE *mtab, *newmtab;
  59.     struct mntent *mp;
  60.     struct mntent mnt;
  61.  
  62.     int flag;
  63.  
  64.     while((c = getopt(argc, argv, "v")) != EOF) {
  65.     switch(c) {
  66.       case 'v':
  67.         opt_verbose = 1;
  68.         break;
  69.       default:
  70.         usage();
  71.         break;
  72.     }
  73.     }
  74.     if(optind < argc) mntdev = argv[optind++];
  75.     if(optind < argc) usage();
  76.  
  77.     if((!opt_all && !mntdev) || (opt_all && mntdev)) usage();
  78.  
  79.     opt_usermount = 1; /* RGtti : only user */
  80.  
  81.     if(geteuid()) {
  82.     fprintf(stderr, "userumount: I have to be installed setuid root!.\n");
  83.     exit(1);
  84.     }
  85.  
  86.     if(opt_usermount) {
  87.     /* scan ufstab for filesystems that ordinary users can umount */
  88.     flag = 0;
  89.     if(!(mtab = setmntent(UFSTAB, "r"))) err(UFSTAB);
  90.     while((mp = getmntent(mtab))) {
  91.         if(!strcmp(mntdev, mp->mnt_fsname)
  92.            || !strcmp(mntdev, mp->mnt_dir)) {
  93.         flag = 1;
  94.         break;
  95.         }
  96.     }
  97.     endmntent(mtab);
  98.  
  99.     if(!flag) {
  100.         fprintf(stderr, "userumount: %s isn't user-unmountable\n", mntdev);
  101.         exit(1);
  102.     }
  103.     }
  104.  
  105.     if(!(newmtab = fdopen(open(LOCK_FILE, O_WRONLY|O_CREAT|O_EXCL, 0666), "w"))) {
  106.     fprintf(stderr, "usermount: A lockfile exists, unmount denied\n");
  107.     exit(1);
  108.     }
  109.     if(!(mtab = setmntent(MTAB_FILE, "r"))) err(MTAB_FILE);
  110.  
  111.      
  112.     flag = 0;
  113.     while((mp = getmntent(mtab))) {
  114.       if(!mp->mnt_opts || !mp->mnt_opts[0]) mp->mnt_opts = "defaults";
  115.       if(!strcmp(mntdev, mp->mnt_fsname)
  116.      || !strcmp(mntdev, mp->mnt_dir)) {
  117.     flag = 1;
  118.     if(do_umount(mp) < 0) {
  119.       addmntent(newmtab, mp);
  120.       fprintf(stderr, "userumount: Umount of %s failed\n",
  121.           mp->mnt_fsname);
  122.     } else {
  123.       /* reset ownership */
  124.       chown(mp->mnt_dir,0,0);
  125.     }
  126.       } else addmntent(newmtab, mp);
  127.     }
  128.  
  129.     if (flag==0) { /* Hmmm... here we have no device in mtab but it is in
  130.               /etc/ufstab. Let's try to umount it neverthless */
  131.       mnt.mnt_type = NULL;
  132.       mnt.mnt_fsname = mntdev;
  133.       if(do_umount(&mnt) < 0) {
  134.     fprintf(stderr, "usermount: Umount of %s failed\n", mntdev);
  135.       }
  136.     }
  137.  
  138.     endmntent(newmtab);
  139.     endmntent(mtab);
  140.  
  141.     unlink(MTAB_FILE);
  142.     link(LOCK_FILE, MTAB_FILE);
  143.     unlink(LOCK_FILE);
  144.  
  145.        
  146.     exit(0);
  147.   
  148. }
  149.  
  150. void err(char * str)
  151. {
  152.     fprintf(stderr, "usermount: %s: %s\n", str, strerror(errno));
  153.     if(access(LOCK_FILE, 0) == 0) unlink(LOCK_FILE);
  154.     exit(1);
  155. }
  156.  
  157. int do_umount(struct mntent *mp)
  158. {
  159.     if(mp->mnt_type && strcmp(mp->mnt_type, MNTTYPE_SWAP) == 0) {
  160.       fprintf(stderr, "userumount: cannot swapoff\n");
  161.       return -1;
  162.     } else {
  163.       if(umount(mp->mnt_fsname) < 0) {
  164.     perror("umount");
  165.     return -1;
  166.       }
  167.     }
  168.  
  169.  
  170.     if(opt_verbose)
  171.       fprintf(stderr, "Unmounted %s\n", mp->mnt_fsname);
  172.  
  173.     return 0;
  174. }
  175.  
  176.